Ideally, software product libraries provide a public view of offered services while hiding implementation details. Separating the public view, or product interface, from the internal implementation details, or private view, allows developers to modify the product without impacting current users. Decoupling the product interface from the internal implementation details, however, is a problem particularly when the interface consists of C++ classes.
A C++ class's private and public views coexist in the class declaration bringing the internal implementation details of the class into the class user's world. As the class evolves to accommodate changing requirements or additional functionality, users of the class must recompile their applications with the new definition regardless of whether or not the change impacts them.
There are, however, several traditional patterns for providing a firewall between a C++ class' behavior and its internals. Use of exemplars and the letter envelope algorithms are two well-known firewall interfaces [see, for example, the book Advanced C++ Programming: Styles and Idioms by James O. Coplien, published in 1992 by Addison-Wesley].
Exemplars support program evolution by exploiting the runtime flexibility of objects to overcome the compile-time nature of classes. Objects take the role traditionally played by classes of defining the runtime object, while classes play the role normally fulfilled by the metaclass. Exemplars accomplish this through objects that perform C++ compiler work during runtime and through generalization of parameter signatures.
In the letter envelope algorithm a lightweight interface object, the envelope, sends messages to the associated internal, or letter, object. The two objects accomplish work by sending messages between themselves. The envelope exposes services of the class while the letter deals with implementation of the services.
Both of these traditional patterns allow the development of class interfaces that hide the implementation of the internal class from the user. However, this advantage comes at the price of loosely coupled classes and generalization or multiple objects needed to do the work of one. Furthermore, without the benefit of C++ strict type checking runtime checks must be performed for errors normally caught at compile-time. These side effects make the application interface more difficult to maintain, prone to runtime errors, and brittle with regard to internal hierarchy updates.
Thus, what is needed is a method to expose class services to an application in a view that is complete enough to allow non-trivial use yet hides all implementation details to allow class evolution. The interface must be a black box object that presents a consistent view of the services offered regardless of the potential varied internal implementations. Furthermore, the interface must provide for close coupling between the internal and interface classes to flag errors at compile-time. Further still, the interface must maintain runtime flexibility and limit object bloat as the product evolves.